﻿using System.Collections.Generic;
using System.Globalization;
using System.Xml;
using BlogsAPI.GeoLocation;
using BlogsAPI.Interfaces;
using Newtonsoft.Json.Linq;

namespace BlogsAPI.Sites
{
    using System.Web;
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Text.RegularExpressions;
    using Abstract;
    using System.Linq;

    /// <summary>
    /// Videohost - mreporter.ru
    /// </summary>
    [BlogServiceAPI(Description = "Mreporter", Link = "http://mreporter.ru")]
    public class Mreporter : BlogServer, IVideoHost
    {
        /// <summary>
        /// http://www.mreporter.ru/reports/37926
        /// </summary>
        private static readonly Regex Validation = new Regex(@"^https?://(?:[-_\w]+\.)?mreporter\.ru/(reports|users)/([\w_]+)", Regexoptions);
        
        /// <summary>
        /// <p class="Views"><span>Просмотры:</span> 122 <i></i></p>
        /// </summary>
        private static readonly Regex viewsNumber = new Regex(@"<[^>]+class\W+views\D+(\d+)\D", Regexoptions);

        /// <summary>
        /// <p class="Comments"><span>Комментарии:</span> 3 <i></i></p>
        /// </summary>
        private static readonly Regex commsNumber = new Regex(@"<[^>]+class\W+messages\D+(\d+)\D", Regexoptions);

        private static readonly Regex uploadDate = new Regex(@"<dt>[^>]+?</dt>\s*<dd>([^<]+)<", Regexoptions);
        /// <summary>
        /// poster: "http://b1.mreporter.ru/c/130816.2.jpg"
        /// </summary>
        private static readonly Regex rThumbnail2 = new Regex(@"<meta[^>]+?property[^>]+?image[^>]+?content\W+([^""']+)\W", Regexoptions);
        private static readonly Regex Title = new Regex(@"<meta[^>]+?property[^>]+?title[^>]+?content[^""']+\W([^""']+)\W", Regexoptions);
        private static readonly Regex About = new Regex(@"<meta[^>]+?property[^>]+?description[^>]+?content[^""']+\W([^""']+)\W", Regexoptions);
        private static readonly Regex Tags = new Regex(@"<meta[^>]+?name[^>]+?keywords[^>]+?content\W+([^""']+)\W", Regexoptions);
       
        private static readonly Regex UserID = new Regex(@"<a[^>]+/users/([^""']+)\W", Regexoptions);
        //private static readonly Regex Place = new Regex(@"Место[^:]+:([^<]+)<br", Regexoptions); //no more

        #region interface: BlogServer

        [DebuggerStepThrough]
        public Mreporter()
        {
            Encoding = Encoding.UTF8;
        }

        public override bool ValidateLink(string link)
        {
            string userName;
            BlogType bt;
            return ValidateLink(link, out userName,out bt);
        }

        /// <summary>
        /// проверка, является ли передаваемый урл чатью этого сервиса
        /// </summary>
        public override Boolean ValidateLink(string link, out string userName, out BlogType bType)
        {
            userName = "";
            bType = BlogType.User;
            var m = Validation.Match(link);
            if (m.Success)
            {
                if (String.CompareOrdinal(m.Groups[1].Value, "users") == 0)
                {
                    userName = m.Groups[2].Value;
                } 
            }
            return m.Success;
        }


        /// <summary>
        /// Получение ссылки на блог блогера
        /// </summary>
        /// <param name="userName">ник блогера</param>
        /// <param name="btype">Тип блога - пользователь или сообщество</param>
        public override String GetBlogLink(string userName, BlogType btype)
        {
            //http://www.mreporter.ru/users/Danka
            return String.Format("http://www.mreporter.ru/users/{0}", userName);
        }

        /// <summary>
        /// Извлечение картинки пользователя
        /// </summary>
        /// <param name="userName">имя блогера</param>
        /// <param name="btype">тип блога</param>
        /// <returns>Прямая ссылка на картинку</returns>
        public override string ExtractAvatar(string userName, BlogType btype)
        {
            return "http://www.mreporter.ru/avatars/0";
        }

        #endregion

        #region IVideoHost

        /// <summary>
        /// Получение данных по ссылке
        /// </summary>
        /// <param name="link"></param>
        /// <returns></returns>
        public Tuple<VideoData, BlogPost> GetVideoData(Uri link)
        {
            var oRet = new Tuple<VideoData, BlogPost>(
                new VideoData(link),
                new BlogPost(link) { Existance = false,Links = 0,Comments = 0});
            try
            {
                if (ValidateLink(link.OriginalString))
                {
                    var myHttpWebRequest = Common.MakeRequest(link.OriginalString);
                        var myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
                        if (myHttpWebResponse.StatusCode == HttpStatusCode.OK)
                        {
                            string reply = new StreamReader(myHttpWebResponse.GetResponseStream()).ReadToEnd();
                            Match img = rThumbnail2.Match(reply);
                            oRet.Item2.Attributes = new PostAttributeCollection();
                            if (img.Success)
                            {
                            //http://b1.mreporter.ru/c/130816.2.210x116.jpg
                                var imgLink = img.Groups[1].Value.Replace(".jpg", ".210x116.jpg");
                                oRet.Item1.Replace = "<a href=\"" +
                                          link.OriginalString + "\"><img src=\"" + imgLink +
                                          "\"/>[Видео]</a>";
                                oRet.Item1.Images += "<img src=\"" + imgLink + "\"/>";
                                oRet.Item2.Attributes.Add(new PostAttribute(PostParams.MediaThumbnail,
                                    imgLink));
                            }
                            //а теперь просмотры!
                            Match vs = viewsNumber.Match(reply);
                            if (vs.Success)
                            {
                                oRet.Item1.Views += int.Parse(vs.Groups[1].Value);
                                oRet.Item2.Views = oRet.Item1.Views;
                            }
                            //комментарии
                            vs = commsNumber.Match(reply);
                            if (vs.Success)
                            {
                                oRet.Item2.Comments += int.Parse(vs.Groups[1].Value);
                            }
                            //
                            Match pDate = uploadDate.Match(reply);
                            if (!pDate.Success || !DateTime.TryParse(pDate.Groups[1].Value.Trim(),
                                new CultureInfo("ru-RU"),DateTimeStyles.AssumeUniversal,
                                out oRet.Item1.Published))
                            {
                                oRet.Item1.Published = DateTime.UtcNow; //чтобы не вставить текущий день
                            }
                            else
                            {
                                oRet.Item1.Published = oRet.Item1.Published.AddHours(-3);//сдвиг в зону UTC
                            }
                            oRet.Item2.Published = oRet.Item1.Published;
                            //формирование поста...
                            MatchCollection mc = Title.Matches(reply);
                            if (mc.Count>0)
                            {
                                oRet.Item1.Title = 
                                oRet.Item2.Subject = 
                                mc[mc.Count-1].Groups[1].Value.Trim();
                            }
                            Match about = About.Match(reply);
                            if (about.Success && about.Groups[1].Value.Length > 10)
                            {
                                oRet.Item1.About =
                                oRet.Item2.Body = 
                                about.Groups[1].Value.Replace("<br/>", String.Empty).Replace(Environment.NewLine, String.Empty).Trim();
                            }
                            about = UserID.Match(reply);
                            if (about.Success)
                            {
                                oRet.Item2.SpecialParam = about.Groups[1].Value;
                            }
                            about = Tags.Match(reply);
                        if (about.Success)
                        {
                            var tags = about.Groups[1].Value.Replace(", ", ",").Trim();
                            oRet.Item2.Attributes.Add(new PostAttribute(PostParams.Tags,
                                tags));
                            //Match place = Place.Match(reply);
                            //if (place.Success)
                            //{

                            var cityNames = tags.Split(',').Where(s => char.IsUpper(s[0]));
                            if (cityNames.Count() > 0)
                            {
                                var loc = GeoMix.GetCoordsFromAddress(String.Join(", ",cityNames.Reverse().Take(2)));
                                if (loc != null)
                                {
                                    oRet.Item2.Attributes.Add(new PostAttribute(PostParams.Location,
                                        String.Format(new CultureInfo("en-US"),
                                            "{0} {1}", loc.Latitude, loc.Longitude))
                                        );
                                }
                            }
                            //}
                        }
                            oRet.Item2.Existance = true;
                            
                            oRet.Item2.Links = 0;

                        }
                        myHttpWebResponse.Close();
                    }
            }
            catch (Exception e1)
            {
                Debug.Write(e1);
            }
            return oRet;
        }

        /// <summary>
        /// Вычисление цифр
        /// </summary>
        readonly static Regex digi = new Regex(@"/(\d+)\.", Regexoptions);

        /// <summary>
        /// Код для размещения на сторонних ресурсах
        /// </summary>
        /// <param name="link"></param>
        /// <returns></returns>
        public string FormEmbedCode(Uri link, String preview = null)
        {
            if (String.IsNullOrEmpty(preview)) return null;
            var m = digi.Match(preview);
            if (m.Success)
            {
                return String.Format(
                    "<iframe width=\"480\" height=\"406\" src=\"http://mreporter.ru/videos/{0}\" frameborder=\"0\" allowfullscreen></iframe>", 
                    m.Groups[1].Value);
            }
            return String.Empty;
        }

        #endregion
    }
}